package com.ssy.lingxi.platform.manage.serviceimpl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ssy.lingxi.common.constant.basic.EnableDisableStatus;
import com.ssy.lingxi.common.constant.basic.FundModeEnum;
import com.ssy.lingxi.common.constant.basic.PlatformRuleTypeEnum;
import com.ssy.lingxi.common.constant.contract.ContractSourceTypeEnum;
import com.ssy.lingxi.common.constant.order.OrderModeEnum;
import com.ssy.lingxi.common.constant.order.OrderTypeEnum;
import com.ssy.lingxi.platform.manage.entity.base.*;
import com.ssy.lingxi.platform.manage.repository.*;
import com.ssy.lingxi.platform.manage.service.IPlatformManageDataInitService;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 平台后台服务数据初始化
 * @author 万宁
 * @version 2.0.0
 * @date 2021-06-09
 */
@Service
public class PlatformManageDataInitServiceImpl implements IPlatformManageDataInitService {
    @Resource
    private JdbcTemplate jdbcTemplate;

    @Resource
    private CountryAreaRepository countryAreaRepository;

    @Resource
    private CurrencyRepository currencyRepository;

    @Resource
    private LanguageRepository languageRepository;

    @Resource
    private AreaRepository areaRepository;

    @Resource
    private SensitiveWordRepository sensitiveWordRepository;

    @Resource
    private PlatformParameterManageRepository platformParameterManageRepository;

    @Resource
    private RuleConfigurationRepository ruleConfigurationRepository;

    /**
     * 初始化平台后台服务数据
     */
    @Override
    public void initPlatformManageServiceData() {
        //初始化货币
        initCurrency();

        //初始化语言
        initLanguage();

        //初始化国家
        initCountryArea();

        //初始化省市区
        initArea();

        //初始化敏感词
        initSensitiveWord();

        // 初始化平台后台 - 平台参数
        initPlatformParameters();

        //初始化平台规则配置
        initRuleConfiguration();
    }



    /**
     * 初始化语言设置
     */
    private void initLanguage() {
        if(countTable("man_language") > 0) {
            return;
        }

        Language language = new Language();
        language.setId(1L);
        language.setCreateTime(System.currentTimeMillis());
        language.setName("中文");
        language.setNameEn("China");
        language.setState(1);
        language.setImgUrl("");
        languageRepository.saveAndFlush(language);
    }

    /**
     * 初始化货币设置
     */
    private void initCurrency() {
        if(countTable("man_currency") > 0) {
            return;
        }

        Currency currency = new Currency();
        currency.setId(1L);
        currency.setCreateTime(System.currentTimeMillis());
        currency.setNameEn("RMB");
        currency.setName("人民币");
        currency.setSymbol("￥");
        currency.setImgUrl("");
        currency.setState(1);
        currencyRepository.saveAndFlush(currency);
    }

    /**
     * 初始化国家
     */
    private void initCountryArea() {
        if(countTable("man_country_area") > 0) {
            return;
        }

        CountryArea area = new CountryArea();
        area.setId(1L);
        area.setCode("1");
        area.setCreateTime(System.currentTimeMillis());
        area.setName("中国");
        area.setNameEn("China");
        Currency currency = currencyRepository.findFirstByName("人民币");
        area.setCurrencyId(currency == null ? 1 : currency.getId());
        Language language = languageRepository.findFirstByName("中文");
        area.setLanguageId(language == null ? 1 : language.getId());
        area.setTelCode("+86");
        area.setTelNumber(11);
        area.setState(1);

        countryAreaRepository.saveAndFlush(area);
    }

    /**
     * 初始化国内省市区
     */
    private void initArea() {
        try {
            if (countTable("man_area") > 0) {
                return;
            }

            alterSequence("man_area_seq");

            org.springframework.core.io.Resource resource = new ClassPathResource("cn_country_area.json");
            ObjectMapper mapper = new ObjectMapper();
            List<Area> countryAreaList = mapper.readValue(resource.getInputStream(), new TypeReference<List<Area>>() {
            });
            countryAreaList.forEach(area -> area.setId(null));

            areaRepository.saveAll(countryAreaList);
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("系统初始化省市区错误：" + e.getMessage());
            System.exit(1);
        }
    }

    /**
     * 初始化敏感词库
     */
    private void initSensitiveWord() {
        try {
            if (countTable("man_sensitive_word") > 0) {
                return;
            }

            alterSequence("man_sensitive_word_seq");

            org.springframework.core.io.Resource resource = new ClassPathResource("sensitive_word.json");
            ObjectMapper mapper = new ObjectMapper();
            List<SensitiveWord> words = mapper.readValue(resource.getInputStream(), new TypeReference<List<SensitiveWord>>() {
            });

            words.forEach(word -> {
                word.setId(null);
                word.setCreateTime(System.currentTimeMillis());
            });

            sensitiveWordRepository.saveAll(words);
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("系统初始化敏感词库错误：" + e.getMessage());
            System.exit(1);
        }
    }

    /**
     * 初始化平台参数配置
     */
    private void initPlatformParameters() {
        if(countTable("man_platform_parameter_manage") > 0) {
            return;
        }

        alterSequence("man_platform_parameter_manage_seq");

        List<PlatformParameterManage> parameters = new ArrayList<>();
        PlatformParameterManage parameter = new PlatformParameterManage();
        parameter.setName("订单取消时间");
        parameter.setCode("A01");
        parameter.setDetails("下单后超过多少小时未支付后自动取消订单");
        parameter.setParameterValue("0");
        parameter.setState(EnableDisableStatus.DISABLE.getCode());
        parameters.add(parameter);

        parameter = new PlatformParameterManage();
        parameter.setName("积分兑换比率");
        parameter.setCode("A02");
        parameter.setDetails("积分与金额兑换比率，如1%表示100积分兑换￥1.00");
        parameter.setParameterValue("1");
        parameter.setState(EnableDisableStatus.ENABLE.getCode());
        parameters.add(parameter);

        parameter = new PlatformParameterManage();
        parameter.setName("佣金比例");
        parameter.setCode("A03");
        parameter.setDetails("手续费为供应商订单交易总额的百分比");
        parameter.setParameterValue("1");
        parameter.setState(EnableDisableStatus.ENABLE.getCode());
        parameters.add(parameter);

        parameter = new PlatformParameterManage();
        parameter.setName("交易评价时间");
        parameter.setCode("A04");
        parameter.setDetails("订单超过多少天未进行评价系统自动默认好评");
        parameter.setParameterValue("30");
        parameter.setState(EnableDisableStatus.ENABLE.getCode());
        parameters.add(parameter);

        parameter = new PlatformParameterManage();
        parameter.setName("商家审核评价内容");
        parameter.setCode("A07");
        parameter.setDetails("默认是1则商家无需审核评价内容；0则商家需审核评价内容");
        parameter.setParameterValue("1");
        parameter.setState(EnableDisableStatus.ENABLE.getCode());
        parameters.add(parameter);

        parameter = new PlatformParameterManage();
        parameter.setName("定位应用ID");
        parameter.setCode("A08");
        parameter.setDetails("用于定位的API的应用的ID");
        parameter.setParameterValue("724e2425058db8160c155784d9e532ab");
        parameter.setState(EnableDisableStatus.ENABLE.getCode());
        parameters.add(parameter);

        platformParameterManageRepository.saveAll(parameters);
    }

    /**
     * 初始化平台规则配置
     */
    private void initRuleConfiguration() {
        if(countTable("man_rule_configuration") > 0) {
            return;
        }

        List<RuleConfiguration> ruleList = new ArrayList<>();

        long idx = 0L;
        ruleList.add(new RuleConfiguration(++idx, 1, PlatformRuleTypeEnum.FUND.getCode(),"平台代收模式","资金归集模式", FundModeEnum.PLATFORM_EXCHANGE.getCode()));
        ruleList.add(new RuleConfiguration(++idx,1, PlatformRuleTypeEnum.FUND.getCode(),"会员直接到账模式","资金归集模式", FundModeEnum.DIRECT_TO_ACCOUNT.getCode()));

        ruleList.add(new RuleConfiguration(++idx,1, PlatformRuleTypeEnum.INVENTORY.getCode(),"按仓位随机扣减（默认）","库存扣减策略", 0));
        ruleList.add(new RuleConfiguration(++idx,1, PlatformRuleTypeEnum.INVENTORY.getCode(),"按仓库物理地址远近顺序扣减","库存扣减策略", 0));

        for (OrderModeEnum orderMode : Arrays.stream(OrderModeEnum.values()).sorted(Comparator.comparingInt(OrderModeEnum::getCode)).collect(Collectors.toList())) {
            ruleList.add(new RuleConfiguration(++idx,1, PlatformRuleTypeEnum.ORDER_MODE.getCode(),orderMode.getName(),"下单模式", orderMode.getCode()));
        }

        for (OrderTypeEnum orderType : Arrays.stream(OrderTypeEnum.values()).sorted(Comparator.comparingInt(OrderTypeEnum::getCode)).collect(Collectors.toList())) {
            ruleList.add(new RuleConfiguration(++idx, 1,PlatformRuleTypeEnum.ORDER_TYPE.getCode(), orderType.getName(),"订单类型", orderType.getCode()));
        }

        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.MARKETING.getCode(),"特价促销","营销活动类型", 0));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.MARKETING.getCode(),"直降促销","营销活动类型", 0));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.MARKETING.getCode(),"折扣促销","营销活动类型", 0));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.MARKETING.getCode(),"满量促销","营销活动类型", 0));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.MARKETING.getCode(),"满额促销","营销活动类型", 0));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.MARKETING.getCode(),"赠送促销","营销活动类型", 0));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.MARKETING.getCode(),"多件促销","营销活动类型", 0));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.MARKETING.getCode(),"组合促销","营销活动类型", 0));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.MARKETING.getCode(),"拼团","营销活动类型", 0));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.MARKETING.getCode(),"抽奖","营销活动类型", 0));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.MARKETING.getCode(),"砍价","营销活动类型", 0));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.MARKETING.getCode(),"秒杀","营销活动类型", 0));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.MARKETING.getCode(),"换购","营销活动类型", 0));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.MARKETING.getCode(),"预售","营销活动类型", 0));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.MARKETING.getCode(),"套餐","营销活动类型", 0));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.MARKETING.getCode(),"试用","营销活动类型", 0));

        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.SETTLEMENT.getCode(),"账期（默认）","结算方式", 0));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.SETTLEMENT.getCode(),"月结","结算方式", 0));

        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.PRODUCT_CATEGORY.getCode(),"只允许使用平台品类与属性","品类与属性使用方式", 0));

        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.PURCHASE_SOURCE.getCode(),"采购询价","采购寻源类型", ContractSourceTypeEnum.PURCHASE_INQUIRY.getCode()));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.PURCHASE_SOURCE.getCode(),"采购招标","采购寻源类型", ContractSourceTypeEnum.PURCHASE_INVITE_BID.getCode()));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.PURCHASE_SOURCE.getCode(),"采购竞价","采购寻源类型", ContractSourceTypeEnum.PURCHASE_VIA_PRICE.getCode()));

        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.PURCHASE_CONTRACT.getCode(),"现结","采购合同付款方式", 0));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.PURCHASE_CONTRACT.getCode(),"账期（默认）","采购合同付款方式", 0));
        ruleList.add(new RuleConfiguration(++idx,1,PlatformRuleTypeEnum.PURCHASE_CONTRACT.getCode(),"月结","采购合同付款方式", 0));
        ruleConfigurationRepository.saveAll(ruleList);
    }

    /**
     * 执行 select count(id) from table 语句
     * @param dbTableName 数据库的表名称
     * @return 表数据行数
     */
    private long countTable(String dbTableName) {
        String sql = "select count(id) as total from " + dbTableName + ";";
        SqlRowSet sqlRowSet = jdbcTemplate.queryForRowSet(sql);
        long total = 0;
        while (sqlRowSet.next()) {
            total = sqlRowSet.getLong("total");
        }
        return total;
    }

    /**
     * 更改序列值为1
     * @param sequenceName 序列名称
     */
    private void alterSequence(String sequenceName) {
        String sql = "alter sequence " + sequenceName + " restart with 1";
        jdbcTemplate.execute(sql);
    }
}
